
#ifndef ACEL_UNIX_ADDR_HPP
#define ACEL_UNIX_ADDR_HPP

#include    <sys/types.h>
#include    <string.h>
#include    <sys/socket.h>
#include    <sys/un.h>

#include    "acel/addr.hpp"

namespace   acel
{

/**
 * @class UNIX_Addr
 *
 * @brief Defines the ``UNIX domain address family'' address format.
 */
class UNIX_Addr : public Addr
{
public:
    // = Initialization methods.
    /// Default constructor.
    UNIX_Addr (void);

    /// Copy constructor.
    UNIX_Addr (const UNIX_Addr &sa);

    /// Creates an UNIX_Addr from a string.
    UNIX_Addr (const char rendezvous_point[]);

    /// Creates an UNIX_Addr from a sockaddr_un structure.
    UNIX_Addr (const sockaddr_un *, int len);

    /// Creates an UNIX_Addr from another UNIX_Addr.
    int set (const UNIX_Addr &sa);

    /// Creates an UNIX_Addr from a string.
    int set (const char rendezvous_point[]);

    /// Creates an UNIX_Addr from a sockaddr_un structure.
    int set (const sockaddr_un *, int len);

    /// Return a pointer to the underlying network address.
    virtual void *getAddr (void) const;

    /// Set a pointer to the underlying network address.
    virtual void setAddr (void *addr, int len);

    /// Transform the current address into string format.
    virtual int toString (char addr[], size_t) const;

    /// Transform the string into the current addressing format.
    virtual int fromString (const char addr[]);

    /// Compare two addresses for equality.
    bool operator == (const UNIX_Addr &sap) const
    {
      return strncmp (this->_unix_addr.sun_path,
                              sap._unix_addr.sun_path,
                              sizeof this->_unix_addr.sun_path) == 0;
    }

    /// Compare two addresses for inequality.
    bool operator != (const UNIX_Addr &sap) const
    {
      return !((*this) == sap); 
    }

    /// Return the path name of the underlying rendezvous point.
    const char *getPathName (void) const
    {
      return this->_unix_addr.sun_path;
    }

    /// Computes and returns hash value.
    virtual unsigned long hash (void) const;

private:
    /// Underlying socket address.
    sockaddr_un _unix_addr;
};

}   // namespace acel

#endif  // ACEL_UNIX_ADDR_HPP
